package com.jyszkj.map.util

import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.widget.ImageView
import android.widget.TextView
import com.blankj.utilcode.util.EncryptUtils
import com.blankj.utilcode.util.ResourceUtils
import com.jyszkj.map.bean.DeviceBean
import com.jyszkj.map.constant.MapConstants
import com.jyszkj.map.filter.BlueFilterConverter
import com.jyszkj.map.filter.GreenFilterConverter
import com.jyszkj.map.filter.LightGreenFilterConverter
import com.jyszkj.map.listener.MapClickListener
import com.jyszkj.map.view.CustomDeviceInfoWindow
import com.jyszkj.map.view.CustomInfoWindow
import com.jyszkj.map.view.NonClickableMarker
import com.jyszkj.osmdroid.map.R
import org.osmdroid.config.Configuration
import org.osmdroid.events.MapEventsReceiver
import org.osmdroid.tileprovider.MapTileProviderArray
import org.osmdroid.tileprovider.MapTileProviderBasic
import org.osmdroid.tileprovider.modules.ArchiveFileFactory
import org.osmdroid.tileprovider.modules.IArchiveFile
import org.osmdroid.tileprovider.modules.MapTileFileArchiveProvider
import org.osmdroid.tileprovider.tilesource.TileSourceFactory
import org.osmdroid.tileprovider.tilesource.XYTileSource
import org.osmdroid.tileprovider.util.SimpleRegisterReceiver
import org.osmdroid.util.GeoPoint
import org.osmdroid.util.MapTileIndex
import org.osmdroid.views.CustomZoomButtonsController
import org.osmdroid.views.MapView
import org.osmdroid.views.overlay.MapEventsOverlay
import org.osmdroid.views.overlay.Marker
import timber.log.Timber
import java.io.File
import java.util.Locale


class MapManager(
    private val context: Context,
    private val mapView: MapView,
    private val terminalType: Int
) {
    // 地图类型枚举
    enum class MapType {
        STANDARD,  // 标准地图
        TERRAIN,    // 地形图
        OFFLINE_TERRAIN //离线地形图
    }

    // 地图主题枚举
    enum class MapTheme {
        BLUE,  // 蓝色滤镜
        GREEN,  // 绿色滤镜
        LIGHT_GREEN,  // 浅绿色滤镜
    }

    private var infoWindow: CustomInfoWindow
    private var deviceInfoWindow: CustomDeviceInfoWindow
    private var isScrollEnabled: Boolean = false
    private var clickListener: MapClickListener? = null
    // 当前地图类型
    private var currentMapType: MapType = MapType.STANDARD
    private var currentMapTheme: MapTheme = MapTheme.BLUE

    // 地图源配置
    private val tileSources = mapOf(
        MapType.STANDARD to object : XYTileSource(
            "OpenStreetMap",
            3, 15, 256, ".png",
            arrayOf(
                "https://map.boeyo.com/gd","https://map2.boeyo.com/gd"
            ),
            "© Boeyo Map Data"
        ) {
            override fun getTileURLString(pMapTileIndex: Long): String {
                // 重写此方法以匹配你的URL格式
                return (baseUrl
                        + "/" + MapTileIndex.getZoom(pMapTileIndex)
                        + "/" + MapTileIndex.getX(pMapTileIndex)
                        + "/" + MapTileIndex.getY(pMapTileIndex)
                        + "/tile" + mImageFilenameEnding)
            }
        },

        MapType.TERRAIN to object : XYTileSource(
            "USGSTopo",
            3, 15, 256, ".png",
            arrayOf("https://map.boeyo.com/gg/dx"),
            "© Boeyo Map Data"
        ) {
            override fun getTileURLString(pMapTileIndex: Long): String {
                // 重写此方法以匹配你的URL格式
                return (baseUrl
                        + "/" + MapTileIndex.getZoom(pMapTileIndex)
                        + "/" + MapTileIndex.getX(pMapTileIndex)
                        + "/" + MapTileIndex.getY(pMapTileIndex)
                        + "/tile" + mImageFilenameEnding)
            }
        },
    )

    val mapEventsReceiver = object : MapEventsReceiver {
        override fun singleTapConfirmedHelper(point: GeoPoint): Boolean {
            mapView.controller.animateTo(point, mapView.zoomLevelDouble, 1500L)
            Timber.d("--------click---------")
            clickListener?.onMapClick(point.longitude,point.latitude)
            return true // 返回 true 表示已处理事件
        }

        override fun longPressHelper(p: GeoPoint): Boolean {
            // 长按事件
            return false // 返回 false 表示不处理
        }
    }

    init {
        // 初始化osmdroid配置
        setupTileProvider()
        val tileSource = mapView.tileProvider.tileSource
        val sourceMinZoom = tileSource.minimumZoomLevel.toDouble()
        val sourceMaxZoom = tileSource.maximumZoomLevel.toDouble()
        mapView.zoomController.setVisibility(CustomZoomButtonsController.Visibility.NEVER)
        mapView.maxZoomLevel = sourceMaxZoom
        mapView.minZoomLevel = sourceMinZoom
        mapView.setMultiTouchControls(true)
        mapView.setUseDataConnection(true)
        val tilesOverlay = mapView.overlayManager.tilesOverlay
        if (tilesOverlay != null) {
            // 隐藏加载时的网格效果
            //tilesOverlay.loadingBackgroundColor = Color.TRANSPARENT
            tilesOverlay.loadingLineColor = Color.TRANSPARENT
        }
        mapView.overlays.add(0,MapEventsOverlay(mapEventsReceiver))
        mapView.setOnTouchListener { v, event ->
            !isScrollEnabled
        }
        infoWindow = CustomInfoWindow(mapView,terminalType)
        deviceInfoWindow = CustomDeviceInfoWindow(mapView,terminalType)
    }

    fun setMapScrollable(enabled: Boolean) {
        isScrollEnabled = enabled
    }

    companion object{
        fun initCache(context: Context) {
            val osmConfig = Configuration.getInstance()
            val cacheDir = File(context.cacheDir, "osmdroid")
            if (!cacheDir.exists()) {
                cacheDir.mkdirs()
            }
            Configuration.getInstance().osmdroidBasePath = cacheDir
            val tilesDir = File(context.cacheDir, "tiles")
            if (!tilesDir.exists()) {
                tilesDir.mkdirs()
            }
            osmConfig.osmdroidTileCache = tilesDir
            // 设置最大缓存大小为 1GB
            osmConfig.tileFileSystemCacheMaxBytes = 1024L * 1024 * 1024
            // 设置当缓存满时，清理掉 50MB 的空间
            osmConfig.tileFileSystemCacheTrimBytes = 50L * 1024 * 1024
            osmConfig.userAgentValue = context.packageName
        }
    }

    fun setMapClickListener(clickListener: MapClickListener) {
        this.clickListener = clickListener
    }

    fun setCenter(lon: Double, lat: Double) {
        val mapController = mapView.controller
        mapController.setCenter(GeoPoint(lat,lon))
    }

    fun setZoom(zoom: Double){
        val tileSource = mapView.tileProvider.tileSource
        val sourceMinZoom = tileSource.minimumZoomLevel.toDouble()
        val sourceMaxZoom = tileSource.maximumZoomLevel.toDouble()
        val mapController = mapView.controller
        if(zoom < sourceMinZoom) {
            mapController.setZoom(sourceMinZoom)
        } else if(zoom > sourceMaxZoom) {
            mapController.setZoom(sourceMaxZoom)
        } else {
            mapController.setZoom(zoom)
        }
    }

    fun zoomIn() {
        val tileSource = mapView.tileProvider.tileSource
        val sourceMaxZoom = tileSource.maximumZoomLevel.toDouble()
        if(mapView.zoomLevelDouble < sourceMaxZoom) {
            mapView.controller.zoomIn()
        }
    }

    fun zoomOut() {
        val tileSource = mapView.tileProvider.tileSource
        val sourceMinZoom = tileSource.minimumZoomLevel.toDouble()
        if(mapView.zoomLevelDouble > sourceMinZoom) {
            mapView.controller.zoomOut()
        }
    }

    fun clearMarker() {
        mapView.overlays.clear()
        mapView.overlays.add(MapEventsOverlay(mapEventsReceiver))
    }

    // 设置瓦片提供者
    private fun setupTileProvider() {
        val tileProvider = MapTileProviderBasic(context)
        mapView.setTileProvider(tileProvider)
        mapView.setTileSource(tileSources[currentMapType])
        mapView.invalidate()
    }

    fun loadZXYStructureZip(context: Context, zipFile: File) {
        // 2. 创建自定义TileSource
        val tileSource = OfflineTileSource(
            "off_line",
            5,  // 最小缩放级别
            5, // 最大缩放级别
            256, // 瓦片大小
            ".png" // 文件扩展名
        )

        // 4. 设置离线地图提供者
        val registerReceiver = SimpleRegisterReceiver(context)
        val archives = arrayOfNulls<IArchiveFile>(1)
        archives[0] = ArchiveFileFactory.getArchiveFile(zipFile)
        val archiveProvider = MapTileFileArchiveProvider(
            registerReceiver,
            tileSource,
            archives
        )

        val tileProvider = MapTileProviderArray(
            tileSource,
            registerReceiver, arrayOf(archiveProvider)
        ).apply {
            // 禁用网络请求
            mapView.setUseDataConnection(false)
        }
        // 5. 应用到MapView
        mapView.setTileProvider(tileProvider)
        mapView.overlayManager.tilesOverlay.loadingLineColor = Color.TRANSPARENT
    }

    // 切换地图类型
    fun switchMapType(mapType: MapType) {
        currentMapType = mapType
        mapView.tileProvider.clearTileCache()
        if(mapType == MapType.OFFLINE_TERRAIN) {
            val path = Configuration.getInstance().osmdroidBasePath.absolutePath + "/offline/5_aJEPm.zip"
            val file = File(path)
            if(!file.exists()) {
                FileUtils.copyAssetToCache(context,"5_aJEPm.zip",Configuration.getInstance().osmdroidBasePath.absolutePath+"/offline")
                val tempFile = File(path)
                val md5 = EncryptUtils.encryptMD5File2String(tempFile)
                if(md5.uppercase() != "DABD1A1DA962E214EEC29615F27CC37A") {
                    Timber.d("MD5不相同1 = ${md5.uppercase()}")
                    com.blankj.utilcode.util.FileUtils.delete(file)
                    FileUtils.copyAssetToCache(context,"5_aJEPm.zip",Configuration.getInstance().osmdroidBasePath.absolutePath+"/offline")
                } else {
                    Timber.d("MD5相同1")
                }
            } else {
                val md5 = EncryptUtils.encryptMD5File2String(file)
                if(md5.uppercase() != "DABD1A1DA962E214EEC29615F27CC37A") {
                    Timber.d("MD5不相同2 = ${md5.uppercase()}")
                    com.blankj.utilcode.util.FileUtils.delete(file)
                    FileUtils.copyAssetToCache(context,"5_aJEPm.zip",Configuration.getInstance().osmdroidBasePath.absolutePath+"/offline")
                } else {
                    Timber.d("MD5相同2")
                }
            }
            loadZXYStructureZip(context,File(path))
        } else {
            val onlineProvider = MapTileProviderBasic(
                context,
                TileSourceFactory.MAPNIK
            ).apply {
                setUseDataConnection(true)
            }
            mapView.setTileProvider(onlineProvider)
            val ti = tileSources[mapType]
            mapView.setTileSource(ti)
            mapView.overlays.add(MapEventsOverlay(mapEventsReceiver))
            mapView.overlayManager.tilesOverlay.loadingLineColor = Color.TRANSPARENT
        }
    }

    fun switchMapTheme(themeType: MapTheme) {
        currentMapTheme = themeType
        when(themeType) {
            MapTheme.BLUE -> {
                val tilesOverlay = mapView.overlayManager.tilesOverlay
                tilesOverlay.setColorFilter(BlueFilterConverter.createComplexFilter())
            }
            MapTheme.LIGHT_GREEN -> {
                val tilesOverlay = mapView.overlayManager.tilesOverlay
                tilesOverlay.setColorFilter(LightGreenFilterConverter.createComplexFilter())
            }
            else -> {
                val tilesOverlay = mapView.overlayManager.tilesOverlay
                tilesOverlay.setColorFilter(GreenFilterConverter.createComplexFilter())
            }
        }
    }

    // 获取当前地图类型
    fun getCurrentMapType(): MapType {
        return currentMapType
    }

    fun getShelterMaker(lon: Double, lat: Double, value: String, address: String?): Marker{
        val marker = getShelterMarker(GeoPoint(lat,lon),value)
        marker.title = address
        marker.infoWindow = infoWindow
        marker.relatedObject = 1
        mapView.overlays.add(marker)
        return marker
    }

    fun getShelterMakerYqy(lon: Double, lat: Double, value: String, address: String?): Marker{
        val marker = getShelterMarkerYqy(GeoPoint(lat,lon),value)
        marker.title = address
        marker.infoWindow = infoWindow
        marker.relatedObject = 1
        mapView.overlays.add(marker)
        return marker
    }

    fun getDeviceMarker(device: DeviceBean): Marker {
        val marker = Marker(mapView)
        marker.relatedObject = device
        marker.infoWindow = deviceInfoWindow
        marker.position = GeoPoint(device.lat,device.lon)
        marker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM)
        marker.icon = BitmapDrawable(context.resources,createDeviceIcon(context,device))
        marker.closeInfoWindow()
        return marker
    }

    fun getWarnMarker(geoPoint: GeoPoint, level: Int, address: String?): Marker {
        val marker = Marker(mapView)
        marker.position = geoPoint
        marker.icon = createWarnMaker(context,level)
        marker.title = address
        marker.relatedObject = level
        marker.infoWindow = infoWindow
        if(!address.isNullOrEmpty()) {
            marker.showInfoWindow()
        }
        return marker
    }

    fun getCurrentLocationMarker(point: GeoPoint): Marker {
        val marker = Marker(mapView)
        marker.position = point
        marker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM)
        marker.icon = BitmapDrawable(context.resources,createCurrentLocationIcon(context))
        marker.title = "当前位置"
        if(currentMapTheme == MapTheme.LIGHT_GREEN) {
            marker.relatedObject = -1
        } else {
            marker.relatedObject = 0
        }
        marker.infoWindow = infoWindow
        return marker
    }

    fun getCurrentLocationMarkerYqy(point: GeoPoint): Marker {
        val marker = Marker(mapView)
        marker.position = point
        marker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM)
        marker.icon = BitmapDrawable(context.resources,createCurrentLocationIcon(context,"YQY"))
        marker.title = "当前位置"
        marker.relatedObject = 0
        marker.infoWindow = infoWindow
        return marker
    }

    private fun getShelterMarker(point: GeoPoint, value: String): Marker {
        val marker = Marker(mapView)
        marker.position = point
        marker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM)
        marker.icon = BitmapDrawable(context.resources,createShelterIcon(context,value))
        return marker
    }

    private fun getShelterMarkerYqy(point: GeoPoint, value: String): Marker {
        val marker = Marker(mapView)
        marker.position = point
        marker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM)
        marker.icon = BitmapDrawable(context.resources,createShelterIconYqy(context,value))
        return marker
    }

    private fun createShelterIcon(
        context: Context,
        value: String
    ): Bitmap {
        // 加载布局
        var view = LayoutInflater.from(context).inflate(R.layout.layout_shelter_maker, null)
        if(terminalType == MapConstants.MAP_TERMINAL_TYPE_CK) {
            view = LayoutInflater.from(context).inflate(R.layout.layout_shelter_maker_ck, null)
        }
        // 设置布局内容
        val valueView = view.findViewById<TextView>(R.id.tv_value)
        valueView.text = value
        when(currentMapTheme) {
            MapTheme.BLUE -> {
                valueView.setBackgroundResource(R.drawable.ic_shelter_marker_blue)
            }
            MapTheme.LIGHT_GREEN -> {
                valueView.setBackgroundResource(R.drawable.ic_shelter_marker_light_green)
            }
            else -> {

            }
        }

        // 测量并布局视图
        view.measure(
            View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
            View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
        )
        view.layout(0, 0, view.measuredWidth, view.measuredHeight)


        // 创建位图
        val bitmap = Bitmap.createBitmap(view.width, view.height, Bitmap.Config.ARGB_8888)
        val canvas = Canvas(bitmap)
        view.draw(canvas)

        return bitmap
    }

    private fun createShelterIconYqy(
        context: Context,
        value: String
    ): Bitmap {
        // 加载布局
        var view = LayoutInflater.from(context).inflate(R.layout.layout_shelter_maker, null)
        if(terminalType == MapConstants.MAP_TERMINAL_TYPE_CK) {
            view = LayoutInflater.from(context).inflate(R.layout.layout_shelter_maker_ck, null)
        }
        // 设置布局内容
        val valueView = view.findViewById<TextView>(R.id.tv_value)
        valueView.text = value
        when(currentMapTheme) {
            MapTheme.BLUE -> {
                valueView.setBackgroundResource(R.drawable.ic_shelter_marker_yqy)
            }
            else -> {

            }
        }

        // 测量并布局视图
        view.measure(
            View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
            View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
        )
        view.layout(0, 0, view.measuredWidth, view.measuredHeight)


        // 创建位图
        val bitmap = Bitmap.createBitmap(view.width, view.height, Bitmap.Config.ARGB_8888)
        val canvas = Canvas(bitmap)
        view.draw(canvas)

        return bitmap
    }

    private fun createDeviceIcon(
        context: Context,
        bean: DeviceBean
    ): Bitmap {
        // 加载布局
        var view = LayoutInflater.from(context).inflate(R.layout.layout_device_maker, null)
        // 设置布局内容
        val makerIv = view.findViewById<ImageView>(R.id.iv_maker)
        when(bean.type) {
            "1" -> {
                //预警终端
                val zdIcon = getZdIcon(bean.onlineStatus)
                if(zdIcon != -1) {
                    makerIv.setImageResource(zdIcon)
                }
            }
            "2" -> {
                //预警喇叭
                val zdIcon = getLbIcon(bean.onlineStatus)
                if(zdIcon != -1) {
                    makerIv.setImageResource(zdIcon)
                }
            }
            "3" -> {
                //桌面终端
                val zdIcon = getDtIcon(bean.onlineStatus)
                if(zdIcon != -1) {
                    makerIv.setImageResource(zdIcon)
                }
            }
            "4" -> {
                //决策终端
                val zdIcon = getCkIcon(bean.onlineStatus)
                if(zdIcon != -1) {
                    makerIv.setImageResource(zdIcon)
                }
            }
        }

        // 测量并布局视图
        view.measure(
            View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
            View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
        )
        view.layout(0, 0, view.measuredWidth, view.measuredHeight)


        // 创建位图
        val bitmap = Bitmap.createBitmap(view.width, view.height, Bitmap.Config.ARGB_8888)
        val canvas = Canvas(bitmap)
        view.draw(canvas)

        return bitmap
    }

    private fun getZdIcon(status: String?): Int {
        return when(status) {
            "0" -> {
                // 离线
                R.drawable.ic_offline_zd
            }
            "1" -> {
                // 在线
                R.drawable.ic_online_zd
            }
            "2" -> {
                // 异常
                R.drawable.ic_online_zd

            }
            else -> -1
        }
    }

    private fun getLbIcon(status: String?): Int {
        return when(status) {
            "0" -> {
                // 离线
                R.drawable.ic_offline_lb
            }
            "1" -> {
                // 在线
                R.drawable.ic_online_lb
            }
            "2" -> {
                // 异常
                R.drawable.ic_online_lb

            }
            else -> -1
        }
    }

    private fun getDtIcon(status: String?): Int {
        return when(status) {
            "0" -> {
                // 离线
                R.drawable.ic_offline_dt
            }
            "1" -> {
                // 在线
                R.drawable.ic_online_dt
            }
            "2" -> {
                // 异常
                R.drawable.ic_online_dt

            }
            else -> -1
        }
    }

    private fun getCkIcon(status: String?): Int {
        return when(status) {
            "0" -> {
                // 离线
                R.drawable.ic_offline_ck
            }
            "1" -> {
                // 在线
                R.drawable.ic_online_ck
            }
            "2" -> {
                // 异常
                R.drawable.ic_online_ck
            }
            else -> -1
        }
    }


    private fun createCurrentLocationIcon(
        context: Context,
        type: String = "BY"
    ): Bitmap {
        // 加载布局
        var view = LayoutInflater.from(context).inflate(R.layout.layout_current_location_maker, null)

        if(type == "YQY") {
            view = LayoutInflater.from(context).inflate(R.layout.layout_current_location_maker_yqy, null)
        }
        if(terminalType == MapConstants.MAP_TERMINAL_TYPE_CK) {
            view = LayoutInflater.from(context).inflate(R.layout.layout_current_location_maker_ck, null)
        }
        val ivMaker = view.findViewById<ImageView>(R.id.iv_maker)
        if(currentMapTheme == MapTheme.LIGHT_GREEN) {
            ivMaker.setImageResource(R.drawable.ic_current_light_green_location)
        }
        // 测量并布局视图
        view.measure(
            View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
            View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
        )
        view.layout(0, 0, view.measuredWidth, view.measuredHeight)


        // 创建位图
        val bitmap = Bitmap.createBitmap(view.width, view.height, Bitmap.Config.ARGB_8888)
        val canvas = Canvas(bitmap)
        view.draw(canvas)

        return bitmap
    }

    private fun createWarnMaker(
        context: Context,
        level: Int
    ): Drawable {
        // 加载布局
        var view = LayoutInflater.from(context).inflate(R.layout.layout_warn_maker, null)
        if(terminalType == MapConstants.MAP_TERMINAL_TYPE_CK) {
            view = LayoutInflater.from(context).inflate(R.layout.layout_warn_maker_ck, null)
        }
        // 设置布局内容
        val makerIv = view.findViewById<ImageView>(R.id.iv_maker)
        when(level) {
            1 -> makerIv.setImageResource(R.drawable.ic_location_blue)
            2 -> makerIv.setImageResource(R.drawable.ic_location_yellow)
            3 -> makerIv.setImageResource(R.drawable.ic_location_orange)
            4 -> makerIv.setImageResource(R.drawable.ic_location_red)
            else -> {
                makerIv.setImageResource(R.drawable.ic_location_blue)
            }
        }

        // 测量并布局视图
        view.measure(
            View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
            View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
        )
        view.layout(0, 0, view.measuredWidth, view.measuredHeight)


        // 创建位图
        val bitmap = Bitmap.createBitmap(view.width, view.height, Bitmap.Config.ARGB_8888)
        val canvas = Canvas(bitmap)
        view.draw(canvas)

        return BitmapDrawable(context.resources,bitmap)
    }
}